(use-modules (8sync)               ; 8sync's agenda and actors
             (8sync systems irc)   ; the irc bot subsystem
             (oop goops)           ; 8sync's actors use GOOPS
             (ice-9 format)        ; basic string formatting
             (ice-9 match)         ; pattern matching
	     (srfi srfi-1))	 ; list manipulation (find)

(load "guiletime.scm")        ; For countdown til next #LGN
(load "wikipedia-crawler.scm")        ; For wikipedia stuff

(define list->string
  (lambda(lis)
    (cond [(null? lis) ""]
	  [else (string-append (car lis)
			       " "
			       (list->string (cdr lis)))])))


(define-class <my-irc-bot> (<irc-bot>))


(define* (run-bot #:key (username "examplebot")
                  (server "irc.freenode.net")
                  (channels '("#lgn")))
  (define hive (make-hive))
    (define irc-bot
    (bootstrap-actor hive <my-irc-bot>
                     #:username username
                     #:server server
                     #:channels channels))
  (run-hive hive '()))


(define-method (handle-line (irc-bot <my-irc-bot>) message
                            speaker channel line emote?)
  
  (define my-name (irc-bot-username irc-bot))

  (define (looks-like-me? str)
    (or (equal? str my-name)
        (equal? str (string-concatenate (list my-name ":")))))

  (define (respond respond-line)
    (<- (actor-id irc-bot) 'send-line channel
	respond-line))

  (cond ((not (or (equal? speaker "1noordinaryspider[m]")
	       (equal? speaker "1noordinaryspider"))) 
	 (match (string-split line #\space)
	   (((? looks-like-me? _) action action-args ...)
	    (match action

;;; BOT TALKING
;;; STRING -> STRING
;;; (STRING (respond STRING))
;;; Takes a string as a first argument (given by speaker)
;;; If it matches it calls (respond STRING) as an anwser

;;;  COMMON BOT COMMANDS
	      ;; Repeat everything
	      ;; (respond (list->string (cdr (string-split line #\space))))
	      ;; ("what" (respond (car action-args)))
	      ("echo" (respond  (string-join action-args " ")))
       
	      ;; The classic botsnack!
	      ("botsnack" (respond  "Yippie! *does a dance!*"))
	      ;; Return greeting
	      ((or "hello" "hello!" "hello." "greetings" "greetings." "greetings!" "Hi" "Hello"
		   "hei" "hei." "hei!" "hi" "hi!") (respond (format #f "Oh hi ~a!" speaker)))

	      ((or "hola" "Hola" "saludos." "saludos")
	       (respond (format #f "Oh hola!! ~a! me gusta hablar español :)" speaker)))

       
	      ;; Help speaker
	      ("help" (respond   (format #f "I am not a helper bot, help yourself ~a!" speaker)))
	      ;; Give time  
	      ((or "time" "Time") (respond  (format #f "It is: ~a UTC" (strftime "%Y-%m-%d %H:%M" (localtime (current-time) "UTC")))))
       
;;; #LibreGameNight BOT COMMANDS
	      ;; Ask noordinaryspider to be quiet
	      ((or "noordinaryspider" "noordinaryspider[m]")  (respond "noordinaryspider I am tired please be quiet"))
	      ;;Info about next LibreGameNight
	      ((or "game" "#lgn" "lgn") 
	       (respond (format #f "We’ll play TripleA 2017–11–25 @ 06:30 Current time is: ~a UTC For more information please visit https://libregamenight.xyz" (strftime "%Y-%m-%d %H:%M" (localtime (current-time) "UTC")))))
					; Time until next LibreGameNight 
					; countdown from guiletime.scm
	      ("countdown" (respond (countdown "2017-11-25 06:30")))
	      ("jadedctrl" (respond "All hail our benevolent dictator for life"))
	      
	      ;;;; Wikipedia crawler
	      ((or "Wikipedia" "wikipedia")
	       (respond (wikipedia (car action-args))))

	      

;;; PUPPY BOT COMMANDS
	      ;; if called in capital letters by speaker
	      ("PUPPY" (respond (format #f "DO NOT YELL AT ME ~a!!" (string-upcase speaker))))
	      ("sit" (respond "i'm a puppppyyy! i wanna ruunnnn!"))
	      ("numnum's" (respond "NUM NUM NUMMMMMMMS"))
	      ("work!" (respond "NEVAH!"))
	      ("sit" (respond "ima puppppyy:C i dun wanna doo itt!" ))
	      ("hate" (respond ":C:C:C meany!!!!"  ))
	      ("cuteness!!" (respond  "awwwwwwwwwwww! us doggies got it good!"))
	      ("woof!" (respond "nononononono I am the dog NAWT YEW!"))
	      ("heater" (respond "aaaaaaaaaaahhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh  =W= <=3"))
	      ("pupster!" (respond (format #f "~aster!" speaker)))
	      ("walk?" (respond "YESS! POTTY TIME! COME ON HOOMAN GET THE LEASH GET THE LEASH! HURRY HURRY!! *goes out for a walk* ahhh i feel much better!"))
	      ("steal" (respond (format #f "C:< *steals ~a's underwear*" speaker)))
	      ("beath"  (respond "what?"))
	      ("bath"  (respond "=W= JK NO BATH NO BATH NOBATH NOOooooooooooooooooooooooooooooooooooooooo"))
	      (">:)"    (respond ":O:O:O:O:O"))

					; If speaker wants to give belly rubs
	      ("belly" (cond [(equal? "rub?" (car action-args))
			      (if (= 0 (random 2))
				  (respond "YES! I LIVE FOR BELLY RUBS!!")
				  (respond "Nooo!! I am tired :C"))]
			     [(equal? "rub" (car action-args))
			      (if (= 0 (random 2))
				  (respond "aaaaaahhhhh =W=")
				  (respond "I don't want belly rubs, I told you I am tired!"))]))
	      ("belly" (cond [(equal? "rub?" (car action-args))
			      (if (= 0 (random 2))
				  (respond "YES! I LIVE FOR BELLY RUBS!!")
				  (respond "Nooo!! I am tired :C"))]
			     [(equal? "rub" (car action-args))
			      (if (= 0 (random 2))
				  (respond "aaaaaahhhhh =W=")
				  (respond "I don't want belly rubs, I told you I am tired!"))]))
	      ("Los" (cond [(equal? "Patos" (car action-args))
			    (respond (format #f "Hi ~a Me gusta perseguir patos :)" speaker))]
			   [(equal? "patos" (car action-args))
			    (respond (format #f "Hi ~a Me gusta perseguir patos :)" speaker))]))	

	
	      ((or "hug" "Hug" "hugs" "Hugs")
	       (respond (format #f "*wags tail pant pant pant thanks ~a!! i love you too!*" speaker)))

	      ("say" (if (equal? "to" (car action-args))
			 (respond (format #f "~a from ~a" (list->string (cdr action-args)) speaker))
			 (respond (string-join action-args " "))))
	      

	      ;; Default
	      (_  (respond (if (= 0 (random 2))
			       "*stupid puppy look*"
			       "*happily wags tail*")))))))))



(run-bot #:username "Puppy_Bot"); be creative!

